/*==================================================
  assessor.js by Somik Raha
  somik@valuefound.org

  Official Home of the Assessor Tool
  http://www.valuefound.org

  License (http://www.gnu.org/licenses/)

  Copyright (c) 2011 Somik Raha
  
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see http://www.gnu.org/licenses/.
  ==================================================*/
var cdfChart = null;
var pdfChart = null;
var assessor = {
	question: "",
	questions: [90,10,75,25,60,40,10,90,25,75,40,60],
	order: [7,2,6,3,5,4,2,7,3,6,4,5],
	setup: function() {
		if (typeof(descriptor)=='undefined') {
			var name = this.getParam("name");
			if (name=="") {
				alert("Missing name of distinction! Please supply by adding to the url: ?name=name of distinction");
				return;
			}
			this.descriptor = new Descriptor(name);
		}
		this.setMinMax();
		this.createGUI();
		this.kDist = new KDistribution(8);	
		dojo.require("dojox.charting.Chart2D");
		makeCharts = function(){
		        cdfChart = new dojox.charting.Chart2D("cdfChart");
		        cdfChart.addPlot("default", {type: "MarkersOnly"});
		        cdfChart.addAxis("x");
		        cdfChart.addAxis("y", {vertical: true});
		        pdfChart = new dojox.charting.Chart2D("pdfChart");
		        pdfChart.addPlot("default", {type: "Lines"});
		        pdfChart.addAxis("x");
		        pdfChart.addAxis("y", {vertical: true});
		};
		dojo.addOnLoad(makeCharts);
	},
	
	setName: function(name) {
		this.descriptor = new Descriptor(name);
	},
	
	createGUI: function() {
		document.getElementById("distinctionName").innerHTML = this.descriptor.assessmentPageLabel;
		this.updateQuestion(1);
		this.pWheel = new ProbabilityWheel(this.descriptor,this.assessed,this.question,document.getElementById("question"),"assessor.","piegraphStandAlone");
		this.pWheel.drawPieGraph();
	},
	
	isCompatibleBrowser: function() {
		var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
        var is_safari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;
        var is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
        return (is_chrome==true || is_safari==true || is_firefox == true);
	},
	isIE: function() {
		return navigator.userAgent.toLowerCase().indexOf('msie') > -1;
	},
	assessed: function(descriptor, probability) {
		var assessmentNum = document.getElementById("assessmentNum").innerHTML;
		var percent = assessor.questions[assessmentNum-1];
		var normalized = (percent/100.0) * (assessor.max-assessor.min) + (assessor.min/1.0);
		normalized = Math.round(normalized);
		if ((assessmentNum-1)% 2 ==0) {
			probability = 100- probability; 
		}
		var index = assessor.order[assessmentNum-1];
		document.getElementById("p"+index).value = probability;
		document.getElementById("v"+index).value = normalized;
		if (assessmentNum == 2 || assessmentNum == 4) {
			assessor.max = Math.min(normalized/(probability/100),assessor.max);
		}
		assessor.message("<b><-- Please press this</b>");
		assessor.enableNextButton();
	},
	
	message: function(msg) {
		document.getElementById("message").innerHTML = msg;
	},
	
	enableNextButton: function() {
		document.getElementById("Next").disabled = false;
	},
	
	disableNextButton: function() {
		document.getElementById("Next").disabled = true;
	},
	
	addPair: function(p,v) {
		this.dataArray[this.dataArray.length] = new Record(p,v);
	},
	
	getParam: function(name) {
	  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	  var regexS = "[\\?&]"+name+"=([^&#]*)";
	  var regex = new RegExp( regexS );
	  var results = regex.exec( window.location.href );
	  if( results == null )
	    return "";
	  else {
		  results[1] = results[1].replace(/%20/gi," ");
		  return results[1];
	  }
	},
	
	showTab: function(num) {
		var rangeError = false;
		var msg = "";
		if (valueOf("min")=="") {
			msg += "Min not defined!<br/>";
			rangeError = true;
		}
		if (valueOf("max")=="") {
			msg += "Max not defined!";
			rangeError = true;
		}
		if (valueOf("max") < valueOf("min")) {
			msg += "Max should be greater than Min!";
			rangeError = true;
		}
		this.showRangeError(msg);
		if (!rangeError) {
			document.getElementById('maintab').tabber.tabShow(num);
			if (num==1) {
				this.setup();
			}
		}
	},
	
	showRangeError: function(msg) {
		document.getElementById("rangeError").innerHTML = msg;
	},
	
	setMinMax: function() {
		this.min = valueOf("min");
		this.max = valueOf("max");
		this.units = valueOf("units");
		if (min/1.0>max/1.0) {
			alert("Error! min should be less than max");
			var k= this.max;
			this.max = this.min;
			this.min = k;
		}
		var assessmentNum = document.getElementById("assessmentNum").innerHTML;
		this.updateQuestion(assessmentNum);
		document.getElementById("p1").value = 0;
		document.getElementById("v1").value = this.min;
		document.getElementById("p8").value = 100;
		document.getElementById("v8").value = this.max;
	},

	nextAssessment: function() {
		var assessmentNum = document.getElementById("assessmentNum").innerHTML;
		if (assessmentNum<6) {
			assessmentNum++;
			document.getElementById("assessmentNum").innerHTML = assessmentNum;
			this.updateQuestion(assessmentNum);
			this.pWheel.setNewBet(this.question);
			this.pWheel.resetProbabilityWheel();
			this.message("");
			this.disableNextButton();
		} else {
			this.showTab(2);
		}
	},
	
	updateQuestion: function(assessmentNum) {
		var percent = this.questions[assessmentNum-1];
		var normalized = (percent/100.0) * (this.max-this.min) + (this.min/1.0);
		normalized = Math.round(normalized);
		if ((assessmentNum-1)% 2 ==0) {
			this.question = this.descriptor.assessmentPageLabel+" being over "+normalized+" "+this.units; 
		} else {
			this.question = this.descriptor.assessmentPageLabel+" being below "+normalized+" "+this.units;
		}
	},
	
	plot: function() {
		this.sortPoints();
		this.kDist.clear();
		var newCount = 8;
		var prevProb = 0;
		for (var i=0;i<8;i++) {
			var probabilityElement = document.getElementById("p"+(i+1));
			var valueElement = document.getElementById("v"+(i+1));
			if (probabilityElement.value != "" && valueElement.value != "") {
				this.kDist.addAssessment(probabilityElement.value, valueElement.value);
			} else {
				newCount = i;
			}
			if (i>0) {
				if (probabilityElement.value/1.0<prevProb/1.0) {
					this.showError("Probabilities must consistently increase. Not so in assessment "+(i+1));
					return;
				}
				prevProb = probabilityElement.value;
			}
		}
		if (newCount != 8) {
			this.showError("Need a minimum of 8 assessments!");
			return;
		} else {
			this.showError("");
		}
		this.makeChart();
		this.discretize();
	},
	
	sortPoints: function() {
		this.dataArray = new Array();
		for (var i=1;i<=8;i++) {
			var p = document.getElementById("p"+i).value;
			var v = document.getElementById("v"+i).value;
			this.addPair(p,v);
		}
		this.dataArray.sort(comparator);
		for (var i=2;i<=7;i++) {
			document.getElementById("p"+i).value = this.dataArray[i-1].probability;
			document.getElementById("v"+i).value = this.dataArray[i-1].value;
		}
	},
	
	discretize: function() {
		var high = Math.round(this.kDist.cdfFor(0.9)*100);
		var med = Math.round(this.kDist.cdfFor(0.5)*100);
		var low = Math.round(this.kDist.cdfFor(0.1)*100);
		lowElement = document.getElementById("low");
		lowElement.innerHTML = low+" "+this.units;
		medElement = document.getElementById("medium");
		medElement.innerHTML = med+" "+this.units;
		highElement = document.getElementById("high");
		highElement.innerHTML = high+" "+this.units;
	},

	showError: function(msg) {
		document.getElementById("error").innerHTML = msg;
	},

	makeChart: function() {
		this.plotPointsOn(cdfChart);
		this.plotCDFon(cdfChart);
		this.plotPDFon(pdfChart);
	},
	
	plotPointsOn: function(chart) {
		var pointArray = new Array();
		s="";
		for (var i=0;i<this.kDist.numAssessments;i++) {
			var assessment = this.kDist.assessments[i];
			var p = this.kDist.assessments[i].probability;
			var v = this.kDist.assessments[i].value;
			pointArray[i] = {x: v, y: p};
			s += v+","+p+"\n";
		}
		chart.addSeries("Assessments", pointArray);
		chart.render();
	},

	plotCDFon: function(chart) {
		var pointArray = new Array();
		var i = 0;
		pointArray[i] = {x:0, y:0};
		i++;
		for (var p=0;p<=100;p+=1) {
			var v = Math.round(this.kDist.cdfFor(p/100)*100);
			pointArray[i] = {x: v, y: p};
			i++;
		}
		var axisMax = this.max;
		pointArray[i] = {x: axisMax, y: 100};
		
		chart.addSeries("CDF", pointArray, {plot: "Lines", stroke: {color:"blue"}});
		chart.render();
	},

	plotPDFon: function(chart) {
		var pointArray = new Array();
		var i = 0;
		pointArray[i] = {x:0, y:0};
		i++;
		for (var p=0;p<=100;p+=1) {
			var v = Math.round(this.kDist.cdfFor(p/100)*100);
			var yValue = Math.round(this.kDist.pdfFor(p/100)*100);
			pointArray[i] = {x: v, y: yValue};
			i++;
		}
		var axisMax = this.max;
		pointArray[i] = {x: axisMax, y: 0};
		chart.addSeries("PDF", pointArray, {plot: "Lines", stroke: {color:"blue"}});
		chart.render();
	}
};

function Descriptor(name) {
	this.assessmentPageLabel = name;
}

function Record(p,v) {
	this.probability = p;
	this.value = v;
}

function comparator(a, b) {
	return a.value - b.value;
}

function valueOf(id) {
	return document.getElementById(id).value;
}